package com.example.config;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.NamingCase;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.template.Template;
import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateEngine;
import cn.hutool.extra.template.TemplateUtil;
import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.resource.StringTemplateResourceLoader;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.util.Map;

public class BeetlIntegrationExample {
    // 自定义 Beetl 模板  引擎适配器
    public static class BeetlTemplateEngine implements TemplateEngine {
        private GroupTemplate groupTemplate;

        @Override
        public TemplateEngine init(TemplateConfig config) {

            try {
                // 创建 Beetl 配置
                Configuration cfg = Configuration.defaultConfiguration();
                //允许本地调用 Java
                cfg.setNativeCall(true);
                cfg.setNativeSecurity("org.beetl.core.DefaultNativeSecurityManager");

                // 指定模板文件的根目录
                groupTemplate = new GroupTemplate(cfg);
                // 注册自定义函数 //转小驼峰
                groupTemplate.registerFunction("toCamelCase", (paras, ctx) -> NamingCase.toCamelCase((String) paras[0]));
                // 注册自定义函数 //转大驼峰
                groupTemplate.registerFunction("toPascalCase", (paras, ctx) -> NamingCase.toPascalCase((String) paras[0]));
                // className
                groupTemplate.registerFunction("getJdbc2JavaEnum", (paras, ctx) -> Jdbc2Java.Jdbc2JavaEnum.getJdbc2JavaEnum((Integer) paras[0]));


                return this;
            } catch (IOException e) {
                throw new RuntimeException("Failed to initialize Beetl TemplateEngine", e);
            }
        }

        /**
         * 获取模板对象
         *
         * @param resource 资源，根据实现不同，此资源可以是模板本身，也可以是模板的相对路径
         * @return
         */
        @Override
        public Template getTemplate(String resource) {
            //判断字符串的的就用StringTemplateResourceLoader
            if (resource.contains("${")) {
                return new BeetlTemplate(groupTemplate.getTemplate(resource, new StringTemplateResourceLoader()));
            }
            return new BeetlTemplate(groupTemplate.getTemplate(resource));
        }
    }

    // 自定义 Beetl   模板适配器
    public static class BeetlTemplate implements Template {
        private org.beetl.core.Template beetlTemplate;

        public BeetlTemplate(org.beetl.core.Template beetlTemplate) {
            this.beetlTemplate = beetlTemplate;
        }

        @Override
        public void render(Map<?, ?> bindingMap, Writer writer) {
            for (Map.Entry<?, ?> entry : bindingMap.entrySet()) {
                beetlTemplate.binding(StrUtil.str((CharSequence) entry.getKey()), entry.getValue());
            }
            beetlTemplate.renderTo(writer);
        }

        @Override
        public void render(Map<?, ?> bindingMap, OutputStream out) {
            for (Map.Entry<?, ?> entry : bindingMap.entrySet()) {
                beetlTemplate.binding(StrUtil.str((CharSequence) entry.getKey()), entry.getValue());
            }
            beetlTemplate.renderTo(out);
        }

        @Override
        public void render(Map<?, ?> bindingMap, File file) {
            for (Map.Entry<?, ?> entry : bindingMap.entrySet()) {
                beetlTemplate.binding(StrUtil.str((CharSequence) entry.getKey()), entry.getValue());
            }
            // 渲染模板
            String result = beetlTemplate.render();

            // 将结果写入文件
            FileUtil.writeUtf8String(result, file);
            System.out.println("Template rendered and written to file successfully.");
        }

        @Override
        public String render(Map<?, ?> bindingMap) {

            for (Map.Entry<?, ?> entry : bindingMap.entrySet()) {
                beetlTemplate.binding(StrUtil.str((CharSequence) entry.getKey()), entry.getValue());
            }
            String render = beetlTemplate.render();
            return render;
        }
    }

    /**
     * 向外提供模板引擎
     *
     * @return
     */
    public static TemplateEngine getTemplateEngine() {
        // 创建 Hutool 的 TemplateConfig
        TemplateConfig templateConfig = new TemplateConfig();
        //复合加载模板（分别从File、ClassPath、Web-root、String方式尝试查找模板）
        //templateConfig.setResourceMode(TemplateConfig.ResourceMode.COMPOSITE);
        //templateConfig.setCharset(StandardCharsets.UTF_8);
        templateConfig.setCustomEngine(BeetlIntegrationExample.BeetlTemplateEngine.class);

        // 创建 Hutool 的 TemplateEngine
        TemplateEngine engine = TemplateUtil.createEngine(templateConfig);
        return engine;
    }
}
